package com.epam.productxslt.transformation;

import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;

public final class StylesheetCache {
	private static ConcurrentHashMap<String, MapEntry> cache = new ConcurrentHashMap<String, MapEntry>();
	private static Lock lock = new ReentrantLock();
	private StylesheetCache(){
		
	}
	public static Transformer newTransformer(String xsltFileName)
            throws TransformerConfigurationException {
        File xsltFile = new File(xsltFileName);
        long xslLastModified = xsltFile.lastModified( );
        lock.lock();
        try{
	        MapEntry entry = cache.get(xsltFileName);
	        if (entry != null) {      
	            if (xslLastModified > entry.lastModified) {
	                entry = null;
	            }
	        }
	        if (entry == null) {
	            Source xslSource = new StreamSource(xsltFile);
	            TransformerFactory transFact = TransformerFactory.newInstance( );
	            Templates templates = transFact.newTemplates(xslSource);
	            entry = new MapEntry(xslLastModified, templates);
	            cache.put(xsltFileName, entry);
	        }
	        return entry.templates.newTransformer();
        } finally {
        	lock.unlock();
        }        
    }
	public static void remove(String xsltFileName) {
		cache.remove(xsltFileName);
	}
	public static void removeAll(){
		cache.clear();
	}
	static class MapEntry {
        long lastModified;
        Templates templates;

        MapEntry(long lastModified, Templates templates) {
            this.lastModified = lastModified;
            this.templates = templates;
        }
    }
}
